<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.3.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/blog/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/blog/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/blog/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/blog/images/logo.svg" color="#222">

<link rel="stylesheet" href="/blog/css/main.css">

<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&display=swap&subset=latin,latin-ext">
<link rel="stylesheet" href="/blog/lib/font-awesome/css/font-awesome.min.css">


<script id="hexo-configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    hostname: new URL('https://guodh.gitee.io/blog').hostname,
    root: '/blog/',
    scheme: 'Pisces',
    version: '7.7.1',
    exturl: false,
    sidebar: {"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},
    copycode: {"enable":true,"show_result":true,"style":null},
    back2top: {"enable":true,"sidebar":false,"scrollpercent":false},
    bookmark: {"enable":false,"color":"#222","save":"auto"},
    fancybox: false,
    mediumzoom: false,
    lazyload: false,
    pangu: false,
    comments: {"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},
    algolia: {
      appID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    },
    localsearch: {"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},
    path: 'search.xml',
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}
  };
</script>

  <meta name="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
<meta property="og:type" content="website">
<meta property="og:title" content="蛋蛋的小屋">
<meta property="og:url" content="https://guodh.gitee.io/blog/page/6/index.html">
<meta property="og:site_name" content="蛋蛋的小屋">
<meta property="og:description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
<meta property="og:locale">
<meta property="article:author" content="RunningEgg">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="https://guodh.gitee.io/blog/page/6/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome: true,
    isPost: false
  };
</script>

  <title>蛋蛋的小屋</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-meta">

    <div>
      <a href="/blog/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">蛋蛋的小屋</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
        <p class="site-subtitle">来了就看看吧，没有刀剑只有故事</p>
  </div>

  <div class="site-nav-toggle">
    <div class="toggle" aria-label="Toggle navigation bar">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>
</div>


<nav class="site-nav">
  
  <ul id="menu" class="menu">
        <li class="menu-item menu-item-home">

    <a href="/blog/" rel="section"><i class="fa fa-fw fa-home"></i>Home</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/blog/about/" rel="section"><i class="fa fa-fw fa-user"></i>About</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/blog/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>Archives</a>

  </li>
        <li class="menu-item menu-item-book">

    <a href="/blog/book/" rel="section"><i class="fa fa-fw fa-archive"></i>book</a>

  </li>
  </ul>

</nav>
</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content">
            

  <div class="posts-expand">
        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://guodh.gitee.io/blog/2018/10/08/2018/%E5%BC%82%E6%AD%A5%E5%BC%8F%E7%BC%96%E7%A8%8B/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.gif">
      <meta itemprop="name" content="RunningEgg">
      <meta itemprop="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="蛋蛋的小屋">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/blog/2018/10/08/2018/%E5%BC%82%E6%AD%A5%E5%BC%8F%E7%BC%96%E7%A8%8B/" class="post-title-link" itemprop="url">异步式编程</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2018-10-08 14:16:13" itemprop="dateCreated datePublished" datetime="2018-10-08T14:16:13+08:00">2018-10-08</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2018-10-14 16:20:53" itemprop="dateModified" datetime="2018-10-14T16:20:53+08:00">2018-10-14</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>多线程是如今程序员所必须掌握的一门“手艺”，随着CPU核数越来越多，只有能充分发挥CPU的性能才能体现一个手艺人的价值。不过好在，随着时代的变化，语言本身也在发展。无论是GO语言的出现还是说框架开始支持多线程的配置，都是为了更好的支持异步式编程。那么，今天来看下Java对于异步式编程的支持吧。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/blog/2018/10/08/2018/%E5%BC%82%E6%AD%A5%E5%BC%8F%E7%BC%96%E7%A8%8B/#more" rel="contents">
                Read more &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://guodh.gitee.io/blog/2018/09/08/2018/%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BA%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.gif">
      <meta itemprop="name" content="RunningEgg">
      <meta itemprop="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="蛋蛋的小屋">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/blog/2018/09/08/2018/%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BA%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/" class="post-title-link" itemprop="url">深入浅出工厂模式</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2018-09-08 09:36:59" itemprop="dateCreated datePublished" datetime="2018-09-08T09:36:59+08:00">2018-09-08</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2018-10-20 15:56:07" itemprop="dateModified" datetime="2018-10-20T15:56:07+08:00">2018-10-20</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>什么是工厂模式? 提供一个用于创建对象的接口(工厂接口)，让其实现类(工厂实现类)决定实例化哪一个类(产品类)，并且由该实现类创建对应类的实例。</p>
<p><strong>两个关键点:</strong></p>
<ol>
<li>让实现类决定哪个</li>
<li>同一类产品
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/blog/2018/09/08/2018/%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BA%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/#more" rel="contents">
                Read more &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://guodh.gitee.io/blog/2018/08/26/2018/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.gif">
      <meta itemprop="name" content="RunningEgg">
      <meta itemprop="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="蛋蛋的小屋">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/blog/2018/08/26/2018/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" class="post-title-link" itemprop="url">面向对象</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2018-08-26 17:26:57" itemprop="dateCreated datePublished" datetime="2018-08-26T17:26:57+08:00">2018-08-26</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2018-09-09 10:19:00" itemprop="dateModified" datetime="2018-09-09T10:19:00+08:00">2018-09-09</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>曾经以为自己对于面向对象还是足够了解的。不就是一个理念嘛，还是Java所一直比比的，就是一些很low的概念，根本不会对我的代码产生任务影响。然而直到这次Code Review才了解到面向对象是一个很重要的概念。</p>
<p>面向对象是现在程序员所必须掌握的重要理念之一，对于面向对象理解程度的深浅直接影响每个程序员是否能否成为一个合格的架构师。那么，就让我们一起从历史的开始讲起。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/blog/2018/08/26/2018/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/#more" rel="contents">
                Read more &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://guodh.gitee.io/blog/2018/08/05/2018/%E5%B7%A5%E5%85%B7%E7%AE%B1/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.gif">
      <meta itemprop="name" content="RunningEgg">
      <meta itemprop="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="蛋蛋的小屋">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/blog/2018/08/05/2018/%E5%B7%A5%E5%85%B7%E7%AE%B1/" class="post-title-link" itemprop="url">工具箱</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2018-08-05 11:29:34" itemprop="dateCreated datePublished" datetime="2018-08-05T11:29:34+08:00">2018-08-05</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-02-28 20:32:49" itemprop="dateModified" datetime="2019-02-28T20:32:49+08:00">2019-02-28</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>最近忙着发版，然而由于新公司每个项目只有2，3个人，所有必须自己承担起发布时出现的各种问题。最近一次上线，发现会出现这种情况，运维懂得很多linux指令以及网络相关的知识，然而完全不懂程序员要发布的代码的处理。甚至会出现，shell脚本报错，找不到build出来的jar包，还得找开发确认。</p>
<p>如今都在推动dev-ops，开发需要承担起更多运维的工作，因此懂得一些常用的排查手段以及命令是必不可少的。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/blog/2018/08/05/2018/%E5%B7%A5%E5%85%B7%E7%AE%B1/#more" rel="contents">
                Read more &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://guodh.gitee.io/blog/2018/07/15/2018/IO%E5%B0%8F%E8%AE%A1/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.gif">
      <meta itemprop="name" content="RunningEgg">
      <meta itemprop="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="蛋蛋的小屋">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/blog/2018/07/15/2018/IO%E5%B0%8F%E8%AE%A1/" class="post-title-link" itemprop="url">IO 小计</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2018-07-15 21:43:14" itemprop="dateCreated datePublished" datetime="2018-07-15T21:43:14+08:00">2018-07-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2018-09-09 10:23:36" itemprop="dateModified" datetime="2018-09-09T10:23:36+08:00">2018-09-09</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>我们都知道IO，网络，内存，CPU是影响计算机性能的比较重要的几个部分。对于I/O，我们经常仅仅停留于概念层的理解，这次我们不妨做点小事情来认识下I/O。来看下如何优化IO来达到提升机器性能。</p>
<blockquote>
<p>给出一个题目： 将一个2GB左右的大型文件，复制到另一处位置，需要多少时间呢？</p>
</blockquote>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/blog/2018/07/15/2018/IO%E5%B0%8F%E8%AE%A1/#more" rel="contents">
                Read more &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://guodh.gitee.io/blog/2018/06/16/2018/%E9%9D%A2%E8%AF%95%E5%B0%8F%E7%BB%93/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.gif">
      <meta itemprop="name" content="RunningEgg">
      <meta itemprop="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="蛋蛋的小屋">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/blog/2018/06/16/2018/%E9%9D%A2%E8%AF%95%E5%B0%8F%E7%BB%93/" class="post-title-link" itemprop="url">面试小结</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>
              

              <time title="Created: 2018-06-16 23:23:23 / Modified: 15:16:18" itemprop="dateCreated datePublished" datetime="2018-06-16T23:23:23+08:00">2018-06-16</time>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>最近一个月都在忙面试以及工作交接的事，好久没写点东西了。不过这次面试过程还是让我学到了很多的东西。希望能记录下来，各位分享。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/blog/2018/06/16/2018/%E9%9D%A2%E8%AF%95%E5%B0%8F%E7%BB%93/#more" rel="contents">
                Read more &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://guodh.gitee.io/blog/2018/05/03/2018/Solr%E5%AD%A6%E4%B9%A0%E6%80%BB%E7%BB%93/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.gif">
      <meta itemprop="name" content="RunningEgg">
      <meta itemprop="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="蛋蛋的小屋">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/blog/2018/05/03/2018/Solr%E5%AD%A6%E4%B9%A0%E6%80%BB%E7%BB%93/" class="post-title-link" itemprop="url">Solr AND SolrCloud 学习记录</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2018-05-03 00:00:01" itemprop="dateCreated datePublished" datetime="2018-05-03T00:00:01+08:00">2018-05-03</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2018-05-02 23:21:53" itemprop="dateModified" datetime="2018-05-02T23:21:53+08:00">2018-05-02</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>最近开始负责其对接Solr的业务，发现除了Solr的语句以及增量全量的方式，还需要很多细节点需要自己去关注。因为搜索组方面除了保证提供稳定性，还需要针对不同的业务场景提供不同的解决方案，因此了解Solr能够解决些什么问题，还是非常重要的。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/blog/2018/05/03/2018/Solr%E5%AD%A6%E4%B9%A0%E6%80%BB%E7%BB%93/#more" rel="contents">
                Read more &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://guodh.gitee.io/blog/2018/04/21/2018/2018-04-19/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.gif">
      <meta itemprop="name" content="RunningEgg">
      <meta itemprop="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="蛋蛋的小屋">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/blog/2018/04/21/2018/2018-04-19/" class="post-title-link" itemprop="url">数据库MVCC、事务回滚</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2018-04-21 00:00:01" itemprop="dateCreated datePublished" datetime="2018-04-21T00:00:01+08:00">2018-04-21</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2018-04-22 23:42:41" itemprop="dateModified" datetime="2018-04-22T23:42:41+08:00">2018-04-22</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>一直以为数据库的使用仅仅是常见的索引优化，以及SQL语句的学习，在者就是在写update的操作的时候记得加上Spring的@Transactional注解。但是在这次的项目中，让我学到了很多我应该注意的细节。</p>
<blockquote>
<ol>
<li>大数据量的操作一定要通过分页去处理，即使是服务端内部的update，也需要自己写一个 while(num &gt; 200) {…} 这种方式去处理。</li>
<li>在加事务的时候，一定要记得减少事务的颗粒度。把需要事务的操作，例如update才去加上事务。</li>
<li>不仅仅是要会使用@Transcation这种注解，在长事务中可以自己去使用Spring提供的TranscationTemplate的这种方式，手动来控制事务的颗粒度。</li>
</ol>
</blockquote>
<p>那么，以上都是一些工程实践的经验，但是如果不能了解事务的本质还是对于数据的理解不够深入，所以这一次来谈谈数据库的事务管理。</p>
<h2 id="MVCC-定义"><a href="#MVCC-定义" class="headerlink" title="MVCC 定义"></a>MVCC 定义</h2><p>MVCC 全称是 Multiversion concurrency control，多版本并发控制。<br>为什么会有这样一个概念呢？ 最初对于数据的控制最稳妥的方案就是顺序进行操作，这样只要保证只有一个用户操作资源，很好的避免了并发问题。但是，效率是极其低下的。</p>
<img src="https://olwr1lamu.qnssl.com/15242358301691.jpg" alt="不同阶段"/>

<p>于是，就有了两段锁 （2PL）类似java中的读写锁概念，由于数据库大量的操作都是读，能够很好的提升读的性能。但是呢，如果一个用户长时间持有写锁，也会导致读锁无法拿到。<br>于是乎，MVCC就出现了。当然，MVCC是一个相当成熟的理论，不同的数据库已经很好的实现了。甚至，如果你有兴趣你也可以自己动手实现一个，当然也有很好的例子可以借鉴。<br>下文是TiDB的对于MVCC的实现的讲解。</p>
<blockquote>
<p><a href="https://zhuanlan.zhihu.com/p/24118962">https://zhuanlan.zhihu.com/p/24118962</a></p>
</blockquote>
<p>顺便插一句，看一个数据库的实现架构还是很有帮助的，而且还是中文的，很棒。</p>
<p>下图是TiDB架构师来我们公司介绍的PPT所讲到的Tikv的逻辑结构层。我们可以看到，基于存储层和事务处之间，夹杂着MVCC的逻辑层。</p>
<img src="https://olwr1lamu.qnssl.com/15242648560948.jpg" width="40%" height="40%" alt="TIDB逻辑结构"/>

<h2 id="如何实现多版本"><a href="#如何实现多版本" class="headerlink" title="如何实现多版本"></a>如何实现多版本</h2><p>实现的方案有两种：版本号和时间戳；<br>只要保证每一次更新操作的序号都是递增的，进而来区分不同的操作。</p>
<h3 id="悲观锁-vs-乐观锁"><a href="#悲观锁-vs-乐观锁" class="headerlink" title="悲观锁 vs 乐观锁"></a>悲观锁 vs 乐观锁</h3><p>为啥这里突然会讲这个呢？因为市场上比较典型的数据库Mysql使用的是悲观锁，PostgreSQL使用的是乐观锁。<br>悲观锁认为冲突时常见的，所以在不同版本的数据之间，有某个版本的数据要进行更新的时候，这个数据就会被锁住。那么此时，无论是哪个版本的这条数据都将无法更新。所以，某种意义上来说Mysql并没有实现MVCC。<br>而PostgreSQL不同，它使用的是乐观锁，每个不同版本的数据都是可以进行操作的，只有在事务commit之前，数据库会对版本号进行校验，一旦发现有冲突的，就进行回滚。</p>
<h2 id="如何回滚数据"><a href="#如何回滚数据" class="headerlink" title="如何回滚数据"></a>如何回滚数据</h2><p>那么当发生冲突的时候怎么办？这就需要undo.log的帮助。undo.log中记录了，数据库发生回滚需要做的操作。</p>
<h3 id="undo和redo关系"><a href="#undo和redo关系" class="headerlink" title="undo和redo关系"></a>undo和redo关系</h3><p>既然说了undo.log，那么肯定要来说说redo.log。undo和redo是一对好基友，有undo就一定有redo（为什么这么肯定，往下看）。<br>undo是用来回滚数据库，而redo是为了保证数据宕机之后能够恢复到宕机前的瞬间。为什么需要redo呢？因为数据库有个将磁盘数据读到内存，在内存中进行处理的操作。如果此时数据库宕机就需要使用redo回到当时的瞬间。<strong>不过需要说明的是，此时的事务是需要回滚的，当把所有的redo做完之后，还需要依据undo进行事务的回滚。</strong></p>
<h3 id="实际操作"><a href="#实际操作" class="headerlink" title="实际操作"></a>实际操作</h3><p>假设有A、B两个数据，值分别为1,2，开始一个事务，事务的操作内容为：把1修改为3，2修改为4，那么实际的记录如下（简化）：</p>
<table>
<thead>
<tr>
<th></th>
<th>数据库操作</th>
<th>undo log</th>
<th>redo log</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>begin;</td>
<td></td>
<td></td>
</tr>
<tr>
<td>2</td>
<td>-&gt;</td>
<td>update A=1</td>
<td></td>
</tr>
<tr>
<td>3</td>
<td>update A=3</td>
<td></td>
<td></td>
</tr>
<tr>
<td>4</td>
<td>-&gt;-&gt;</td>
<td></td>
<td>update A=3</td>
</tr>
<tr>
<td>5</td>
<td>-&gt;</td>
<td>update B=2</td>
<td></td>
</tr>
<tr>
<td>6</td>
<td>update B=4</td>
<td></td>
<td></td>
</tr>
<tr>
<td>7</td>
<td>-&gt;-&gt;</td>
<td></td>
<td>update B=4</td>
</tr>
<tr>
<td>8</td>
<td>commit;</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h3 id="优化处理"><a href="#优化处理" class="headerlink" title="优化处理"></a>优化处理</h3><p>而且，为了能够更好的处理redo.log和undo.log，InnoDb直接机智的把undo.log当做redo.log来处理。这样直接就能用一种格式的来处理这俩兄弟。处理的结果如下：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">记录<span class="number">1</span>: <span class="operator">&lt;</span>trx1, Undo log <span class="keyword">insert</span> <span class="operator">&lt;</span>undo_insert …<span class="operator">&gt;&gt;</span></span><br><span class="line">记录<span class="number">2</span>: <span class="operator">&lt;</span>trx1, <span class="keyword">insert</span> A…<span class="operator">&gt;</span></span><br><span class="line">记录<span class="number">3</span>: <span class="operator">&lt;</span>trx1, Undo log <span class="keyword">insert</span> <span class="operator">&lt;</span>undo_update …<span class="operator">&gt;&gt;</span></span><br><span class="line">记录<span class="number">4</span>: <span class="operator">&lt;</span>trx1, <span class="keyword">update</span> B…<span class="operator">&gt;</span></span><br><span class="line">记录<span class="number">5</span>: <span class="operator">&lt;</span>trx1, Undo log <span class="keyword">insert</span> <span class="operator">&lt;</span>undo_delete …<span class="operator">&gt;&gt;</span></span><br><span class="line">记录<span class="number">6</span>: <span class="operator">&lt;</span>trx1, <span class="keyword">delete</span> C…<span class="operator">&gt;</span></span><br><span class="line">记录<span class="number">7</span>: <span class="operator">&lt;</span>trx1, <span class="keyword">insert</span> C<span class="operator">&gt;</span></span><br><span class="line">记录<span class="number">8</span>: <span class="operator">&lt;</span>trx1, <span class="keyword">update</span> B <span class="keyword">to</span> <span class="keyword">old</span> <span class="keyword">value</span><span class="operator">&gt;</span></span><br><span class="line">记录<span class="number">9</span>: <span class="operator">&lt;</span>trx1, <span class="keyword">delete</span> A<span class="operator">&gt;</span></span><br></pre></td></tr></table></figure>
<p>同时，由于是顺序写，能大大的提升性能。</p>
<h2 id="Mysql版本问题"><a href="#Mysql版本问题" class="headerlink" title="Mysql版本问题"></a>Mysql版本问题</h2><p>那么就让我们开两个客户端来实验一下我们做的判断。</p>
<p>实验一：</p>
<table>
<thead>
<tr>
<th></th>
<th>客户端1操作</th>
<th>客户端2操作</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>begin;</td>
<td></td>
</tr>
<tr>
<td>2</td>
<td></td>
<td>begin;</td>
</tr>
<tr>
<td>3</td>
<td></td>
<td>select * from test where id = 1; 结果aa</td>
</tr>
<tr>
<td>4</td>
<td>update test set name = ‘aa11’ where id = 1;</td>
<td></td>
</tr>
<tr>
<td>5</td>
<td></td>
<td>select * from test where id = 1; 结果aa</td>
</tr>
<tr>
<td>6</td>
<td>commit;</td>
<td></td>
</tr>
<tr>
<td>7</td>
<td></td>
<td>select * from test where id = 1; 结果aa</td>
</tr>
<tr>
<td>8</td>
<td></td>
<td>commit;</td>
</tr>
<tr>
<td>9</td>
<td></td>
<td>select * from test where id = 1; 结果aa11</td>
</tr>
</tbody></table>
<p>不知各位看官，看到实验一是否想到一个问题，为什么客户端1commit之后，客户端2还是不能够看到更新后的数据？因为Mysql默认实现的是可重复读，如果读到的数据每一次都有可能不一样，就违背了隔离级别的语义。</p>
<p>实验二：</p>
<table>
<thead>
<tr>
<th></th>
<th>客户端1操作</th>
<th>客户端2操作</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>begin;</td>
<td></td>
</tr>
<tr>
<td>2</td>
<td></td>
<td>begin;</td>
</tr>
<tr>
<td>3</td>
<td>update test set name = ‘aa22’ where id = 1;</td>
<td></td>
</tr>
<tr>
<td>4</td>
<td></td>
<td>update test set name = ‘aa22’ where id = 1; 结果：超时</td>
</tr>
<tr>
<td>5</td>
<td></td>
<td>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction</td>
</tr>
</tbody></table>
<h3 id="遇到死锁如何解决"><a href="#遇到死锁如何解决" class="headerlink" title="遇到死锁如何解决"></a>遇到死锁如何解决</h3><p>这里还可以通过别的方式来看我们想要的结果，当然如果遇到死锁的问题的时候，也是一个很好的查问题的方法。</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">show</span> engine innodb status;</span><br><span class="line"><span class="keyword">show</span> <span class="keyword">full</span> processlist; </span><br></pre></td></tr></table></figure>
<img src="https://olwr1lamu.qnssl.com/15243167048994.jpg" alt="show full processlist"/>

<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- information_schem库</span></span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> INNODB_LOCKS;</span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> INNODB_TRX;</span><br></pre></td></tr></table></figure>
<img src="https://olwr1lamu.qnssl.com/15243162433823.jpg" alt="select * from INNODB_LOCKS"/>


<h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><p>说说MySQL中的Redo log Undo log都在干啥: <a href="https://www.cnblogs.com/xinysu/p/6555082.html">https://www.cnblogs.com/xinysu/p/6555082.html</a><br>浅谈数据库并发控制 - 锁和 MVCC：<a href="https://draveness.me/database-concurrency-control">https://draveness.me/database-concurrency-control</a><br>MySQL 四种事务隔离级的说明：<a href="http://www.cnblogs.com/zhoujinyi/p/3437475.html">http://www.cnblogs.com/zhoujinyi/p/3437475.html</a></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://guodh.gitee.io/blog/2018/03/11/2018/CMS%E6%94%B6%E9%9B%86%E5%99%A8vsG1%E6%94%B6%E9%9B%86%E5%99%A8/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.gif">
      <meta itemprop="name" content="RunningEgg">
      <meta itemprop="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="蛋蛋的小屋">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/blog/2018/03/11/2018/CMS%E6%94%B6%E9%9B%86%E5%99%A8vsG1%E6%94%B6%E9%9B%86%E5%99%A8/" class="post-title-link" itemprop="url">CMS收集器 VS G1收集器</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>
              

              <time title="Created: 2018-03-11 19:40:41 / Modified: 22:26:50" itemprop="dateCreated datePublished" datetime="2018-03-11T19:40:41+08:00">2018-03-11</time>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>最近公司，将线上的GC逐步配置成了G1收集器，同时Java9中G1也成为了默认的收集器。所以作为一个程序员，不得不了解下G1到底是个什么结构，凭什么他能够干掉CMS收集器。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/blog/2018/03/11/2018/CMS%E6%94%B6%E9%9B%86%E5%99%A8vsG1%E6%94%B6%E9%9B%86%E5%99%A8/#more" rel="contents">
                Read more &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://guodh.gitee.io/blog/2018/03/03/2018/JVM%E7%BA%BF%E4%B8%8A%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5%E5%B7%A5%E5%85%B7/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.gif">
      <meta itemprop="name" content="RunningEgg">
      <meta itemprop="description" content="写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="蛋蛋的小屋">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/blog/2018/03/03/2018/JVM%E7%BA%BF%E4%B8%8A%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5%E5%B7%A5%E5%85%B7/" class="post-title-link" itemprop="url">JVM线上问题排查工具</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2018-03-03 22:32:00" itemprop="dateCreated datePublished" datetime="2018-03-03T22:32:00+08:00">2018-03-03</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2018-03-11 22:23:43" itemprop="dateModified" datetime="2018-03-11T22:23:43+08:00">2018-03-11</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>编程语言种类繁多，要将各种语言分门别类，也是颇难。但是有一个分类的角度，就是看这门语言有没有GC。举几个例子</p>
<ul>
<li>没有GC的语言<br>C++，Rust…</li>
<li>有GC的语言<br>JAVA，Go，Lua，Python，PHP…</li>
</ul>
<h2 id="GC语言作用"><a href="#GC语言作用" class="headerlink" title="GC语言作用"></a>GC语言作用</h2><p>可以看到在GC语言中，有大量业务代码所需要用到的语言。<br>让程序员从管理内存的痛苦中解脱出来，估计是这类语言最大的愿景吧。愿望永远是美好的，但是现实总是残酷的。当我们享受机器替我们管理内存垃圾的轻松的时候，我们也不得不面对各种问题。</p>
<h4 id="GC问题1：STOP-THE-WORLD"><a href="#GC问题1：STOP-THE-WORLD" class="headerlink" title="GC问题1：STOP THE WORLD"></a>GC问题1：STOP THE WORLD</h4><p>什么是STOP THE WORLD？有一个很好的例子，当你的妈妈要给你打扫卧室的时候，一定会让你停止丢垃圾。（否则你妈妈肯定让你死的很难看。）</p>
<p>如何考虑减少STP（STOP THE WORLD缩写，以下都用STP指代）的时间，避免在业务高峰期出现STP的现象，这都是作为一名程序员所需要考虑的。</p>
<h4 id="GC问题2：OUT-OF-MEMORY"><a href="#GC问题2：OUT-OF-MEMORY" class="headerlink" title="GC问题2：OUT OF MEMORY"></a>GC问题2：OUT OF MEMORY</h4><p>内存溢出。机器永远无法像人一样思考各种前因后果，它只会按照一定的逻辑进行处理。然而，往往有些时候，一些错误的业务逻辑，导致垃圾没有及时清理，容器占用过多的内存，而威胁到了操作系统。那么很对不起，机器就只能把容器给kill掉了。</p>
<h4 id="GC问题小结："><a href="#GC问题小结：" class="headerlink" title="GC问题小结："></a>GC问题小结：</h4><p>铺垫了那么多，说明了两个问题：</p>
<ol>
<li>GC有利有弊</li>
<li>作为一名GC语言的开发者，你必须去处理GC问题所带来的弊端</li>
</ol>
<h2 id="JVM线上问题排查工具"><a href="#JVM线上问题排查工具" class="headerlink" title="JVM线上问题排查工具"></a>JVM线上问题排查工具</h2><p>作为一个JVM语言开发者，其实是挺幸运的一件事儿。因为JVM负担起了GC的任务，将更多的问题抛给了JVM层。JVM提供给了开发者不同的GC收集器，开发者可以根据不同的使用场景来配置使用不同的GC收集器，甚至有好多的公司提供了不同的JVM选型（例如，R大的公司 <a href="https://cn.azul.com/">https://cn.azul.com/</a> ）提供了更高效的GC收集。</p>
<p>同时，JVM提供了很多工具，方便开发者来发现解决GC带来的各种问题。逼逼了这么久，终于到了展示一些实用工具的时候了。那么接下来，笔者将按照自己排查问题的思路，写下如何使用这些工具。</p>
<h3 id="1-查看日志"><a href="#1-查看日志" class="headerlink" title="1.查看日志"></a>1.查看日志</h3><p>启动时添加参数：**-XX:PrintGCDetails**</p>
<p>当线上发生问题的时候，第一步永远是观察GC日志，日志中记录了太多有价值的信息。看日志的前提，当然是理解日志。不同的收集器打印的日志，格式不同，但大体一样。</p>
<p>先来看第一个：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">2018</span>-<span class="number">03</span>-02T14:<span class="number">58</span>:<span class="number">27.325</span>+0800: <span class="number">2432.757</span>: [ParNew: 4909K-&gt;343K(4928K), <span class="number">0.0106576</span> secs] 123196K-&gt;118740K(176320K), <span class="number">0.0110674</span> secs] </span><br><span class="line">[Times: user=<span class="number">0.01</span> sys=<span class="number">0.00</span>, real=<span class="number">0.01</span> secs]</span><br></pre></td></tr></table></figure>
<img src="https://olwr1lamu.qnssl.com/15201355406480.jpg" alt="GC日志"/>


<p>第二个CMS收集器，处理老年代</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">2018</span>-<span class="number">03</span>-02T14:<span class="number">57</span>:<span class="number">28.559</span>+0800: <span class="number">2373.991</span>: [GC (CMS Initial Mark) [<span class="number">1</span> CMS-initial-mark: 158393K(171392K)] 159765K(176320K), <span class="number">0.0122127</span> secs] [Times: user=<span class="number">0.01</span> sys=<span class="number">0.00</span>, real=<span class="number">0.02</span> secs]</span><br><span class="line"><span class="number">2018</span>-<span class="number">03</span>-02T14:<span class="number">57</span>:<span class="number">28.571</span>+0800: <span class="number">2374.004</span>: [CMS-concurrent-mark-start]</span><br><span class="line"><span class="number">2018</span>-<span class="number">03</span>-02T14:<span class="number">57</span>:<span class="number">28.877</span>+0800: <span class="number">2374.309</span>: [CMS-concurrent-mark: <span class="number">0.306</span>/<span class="number">0.306</span> secs] [Times: user=<span class="number">0.31</span> sys=<span class="number">0.00</span>, real=<span class="number">0.30</span> secs]</span><br><span class="line"><span class="number">2018</span>-<span class="number">03</span>-02T14:<span class="number">57</span>:<span class="number">28.878</span>+0800: <span class="number">2374.310</span>: [CMS-concurrent-preclean-start]</span><br><span class="line"><span class="number">2018</span>-<span class="number">03</span>-02T14:<span class="number">57</span>:<span class="number">28.881</span>+0800: <span class="number">2374.314</span>: [CMS-concurrent-preclean: <span class="number">0.004</span>/<span class="number">0.004</span> secs] [Times: user=<span class="number">0.00</span> sys=<span class="number">0.00</span>, real=<span class="number">0.01</span> secs]</span><br><span class="line">2018-03-02T14:57:28.884+0800: 2374.317: [GC (CMS Final Remark) [YG occupancy: 1830 K (4928 K)]2018-03-02T14:57:28.885+0800: 2374.317: [Rescan (parallel) , 0.0085246 secs]2018-03-02T14:57:28.893+0800: 2374.325: [weak refs processing, 0.0013466 secs]2018-03-02T14:57:28.894+0800: 2374.327: [class unloading, 0.0853379 secs]2018-03-02T14:57:28.980+0800: 2374.412: [scrub symbol table, 0.0289180 secs]2018-03-02T14:57:29.009+0800: 2374.441: [scrub string table, 0.0021484 secs][1 CMS-remark: 158393K(171392K)] 160224K(176320K), 0.1484632 secs] [Times: user=0.15 sys=0.00, real=0.15 secs]</span><br><span class="line"></span><br><span class="line"><span class="number">2018</span>-<span class="number">03</span>-02T14:<span class="number">57</span>:<span class="number">29.035</span>+0800: <span class="number">2374.467</span>: [CMS-concurrent-sweep-start]</span><br><span class="line"><span class="number">2018</span>-<span class="number">03</span>-02T14:<span class="number">57</span>:<span class="number">29.147</span>+0800: <span class="number">2374.579</span>: [CMS-concurrent-sweep: <span class="number">0.112</span>/<span class="number">0.112</span> secs] [Times: user=<span class="number">0.11</span> sys=<span class="number">0.00</span>, real=<span class="number">0.11</span> secs]</span><br><span class="line"><span class="number">2018</span>-<span class="number">03</span>-02T14:<span class="number">57</span>:<span class="number">29.147</span>+0800: <span class="number">2374.580</span>: [CMS-concurrent-reset-start]</span><br><span class="line"><span class="number">2018</span>-<span class="number">03</span>-02T14:<span class="number">57</span>:<span class="number">29.148</span>+0800: <span class="number">2374.580</span>: [CMS-concurrent-reset: <span class="number">0.001</span>/<span class="number">0.001</span> secs] [Times: user=<span class="number">0.00</span> sys=<span class="number">0.00</span>, real=<span class="number">0.00</span> secs]</span><br></pre></td></tr></table></figure>
<h3 id="2-JStat-JVM-Statistics-Monitoring-Tool"><a href="#2-JStat-JVM-Statistics-Monitoring-Tool" class="headerlink" title="2.JStat (JVM Statistics Monitoring Tool)"></a>2.JStat (JVM Statistics Monitoring Tool)</h3><p>一般看完日志之后，都会想知道GC进行的次数以及GC所耗费的时间，甚至是当前heap中，不同区域的使用情况。这个时候就可以使用命令:<br>jstat -gcutil pid</p>
<img src="https://olwr1lamu.qnssl.com/15201756754843.jpg" alt="jstat"/>

<p>以上S0，S1代表Survivor0，Survivor1，E代表Eden，o代表老年代，M代表永生代<br>YGCT和FGCT分别代表，年轻代GC的时间，老年代GC的时间。GCT代表总的耗费时间。</p>
<h3 id="3-JMap-JVM-Memory-Map-for-java"><a href="#3-JMap-JVM-Memory-Map-for-java" class="headerlink" title="3.JMap (JVM Memory Map for java)"></a>3.JMap (JVM Memory Map for java)</h3><p>当你发现JVM在不断的FULL GC的时候或者报错OOM了，这个时候一般都是发生了内存泄漏，就需要将堆dump下来。一般的操作步骤：</p>
<ol>
<li>获取java的进程id（pid）</li>
<li>dump堆</li>
<li>使用工具分析dump文件</li>
</ol>
<h4 id="获取java的进程id（pid）"><a href="#获取java的进程id（pid）" class="headerlink" title="获取java的进程id（pid）"></a>获取java的进程id（pid）</h4><p>可以使用命令：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ps -ef | grep java</span><br></pre></td></tr></table></figure>
<p>输入之后可以看到，以下结果。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">501</span>   <span class="number">555</span>     <span class="number">1</span>   <span class="number">0</span> Thu10AM ??         <span class="number">1</span>:<span class="number">49.96</span> /usr/bin/java -Xms2g -Xmx2g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=<span class="number">75</span> -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -server -Djava.awt.headless=<span class="keyword">true</span> -Dfile.encoding=UTF-<span class="number">8</span> -Djna.nosys=<span class="keyword">true</span> -Dio.netty.noUnsafe=<span class="keyword">true</span> -Dio.netty.noKeySetOptimization=<span class="keyword">true</span> -Dlog4j.shutdownHookEnabled=<span class="keyword">false</span> -Dlog4j2.disable.jmx=<span class="keyword">true</span> -Dlog4j.skipJansi=<span class="keyword">true</span> -XX:+HeapDumpOnOutOfMemoryError -Des.path.home=/usr/local/Cellar/elasticsearch/<span class="number">5.0</span><span class="number">.1</span>/libexec -cp /usr/local/Cellar/elasticsearch/<span class="number">5.0</span><span class="number">.1</span>/libexec/lib/elasticsearch-<span class="number">5.0</span><span class="number">.1</span>.jar:/usr/local/Cellar/elasticsearch/<span class="number">5.0</span><span class="number">.1</span>/libexec/lib/org.elasticsearch.bootstrap.Elasticsearch</span><br><span class="line"><span class="number">501</span>   <span class="number">722</span>     <span class="number">1</span>   <span class="number">0</span> Thu10AM ??         <span class="number">2</span>:<span class="number">31.69</span> /Applications/Nutstore.app/Contents/Resources/NutstoreJavaBE.app/Contents/MacOS/JavaAppLauncher --delayLaunch <span class="number">15</span> --retina --java-socket /Users/guodanhao/Library/Group Containers/net.nutstore.osxapp.socket_group/java_s.sock --cocoa-socket /Users/guodanhao/Library/Group Containers/net.nutstore.osxapp.socket_group/cocoa_s.sock</span><br><span class="line"><span class="number">501</span> <span class="number">17141</span> <span class="number">97476</span>   <span class="number">0</span>  <span class="number">3</span>:02PM ttys003    <span class="number">0</span>:<span class="number">00.00</span> grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn java</span><br></pre></td></tr></table></figure>

<p>或者结合JVM提供的工具JPS，直接输入:jps (JVM Process status)<br>(pid + 应用名)</p>
<h4 id="dump堆"><a href="#dump堆" class="headerlink" title="dump堆"></a>dump堆</h4><p>使用JMap来dump堆。<br>使用命令：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jmap -dump:format=b,file=java.hprof <span class="number">555</span>（第一步获取的pid）</span><br></pre></td></tr></table></figure>
<p>当使用的是Jetty的时候，就需要用：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo -u jetty jmap -dump:format=b,file=java.hprof <span class="number">30201</span></span><br></pre></td></tr></table></figure>
<p>会在当前目录生成java.hprof的文件.使用scp或者跳板机下载java.hprof</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scp root<span class="meta">@ip</span>:/opt/jetty/java.hprof /本机地址</span><br></pre></td></tr></table></figure>
<h4 id="分析dump文件"><a href="#分析dump文件" class="headerlink" title="分析dump文件"></a>分析dump文件</h4><p>使用Jhat或者MAT来分析。<br>推荐使用MAT，它是Eclipse的一个插件，强大的可视化功能</p>
<img src="https://olwr1lamu.qnssl.com/15201478920541.jpg" alt="GC日志"/>

<p>不用以为它只有简单的图形展示功能，如何使用可以看下面这个介绍<br><a href="http://childe.net.cn/2017/03/24/MAT-Memory-Analyzer-Tool-%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/">http://childe.net.cn/2017/03/24/MAT-Memory-Analyzer-Tool-%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/</a></p>
<p>除了能dump出堆，jmap还能很好的查看heap的配置，以及年轻代和老年代的使用情况。<br>命令:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jmap -heap pid</span><br></pre></td></tr></table></figure>
















      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

  </div>

  
  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/blog/page/5/"><i class="fa fa-angle-left" aria-label="Previous page"></i></a><a class="page-number" href="/blog/">1</a><span class="space">&hellip;</span><a class="page-number" href="/blog/page/5/">5</a><span class="page-number current">6</span><a class="page-number" href="/blog/page/7/">7</a><span class="space">&hellip;</span><a class="page-number" href="/blog/page/9/">9</a><a class="extend next" rel="next" href="/blog/page/7/"><i class="fa fa-angle-right" aria-label="Next page"></i></a>
  </nav>



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let activeClass = CONFIG.comments.activeClass;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          Table of Contents
        </li>
        <li class="sidebar-nav-overview">
          Overview
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">RunningEgg</p>
  <div class="site-description" itemprop="description">写下我的点点滴滴，写下我对这个世界的看法，还有我内心锁崇拜的技术</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/blog/archives/">
        
          <span class="site-state-item-count">89</span>
          <span class="site-state-item-name">posts</span>
        </a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">24</span>
        <span class="site-state-item-name">tags</span>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="mailto:guodh_1@163.com" title="E-Mail → mailto:guodh_1@163.com" rel="noopener" target="_blank"><i class="fa fa-fw fa-envelope"></i>E-Mail</a>
      </span>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">RunningEgg</span>
</div>
  <div class="powered-by">Powered by <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> v5.3.0
  </div>
  <span class="post-meta-divider">|</span>
  <div class="theme-info">Theme – <a href="https://pisces.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Pisces</a> v7.7.1
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/blog/lib/anime.min.js"></script>
  <script src="/blog/lib/velocity/velocity.min.js"></script>
  <script src="/blog/lib/velocity/velocity.ui.min.js"></script>

<script src="/blog/js/utils.js"></script>

<script src="/blog/js/motion.js"></script>


<script src="/blog/js/schemes/pisces.js"></script>


<script src="/blog/js/next-boot.js"></script>




  















  

  

</body>
</html>
